package vip.xiaonuo.integrationconfig.service;

import org.json.JSONObject;
import org.json.XML;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import vip.xiaonuo.integrationconfig.model.Attribute;
import vip.xiaonuo.integrationconfig.model.ConfigFileInfo;
import vip.xiaonuo.integrationconfig.model.DefaultConfiguration;
import vip.xiaonuo.integrationconfig.param.ConfigSaveParam;

import javax.annotation.Resource;
import java.io.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class IntegrationService {

    @Resource
    private RedissonClient client;

    private static final String FILE_DIR = "classpath:integrationconfig/";

    private static final String FILE_PRE = "values.";

    private static final String FILE_SUF = ".xml";

    private static final String CONFIG_PRE = "INTEGRATION_CONFIG_";

    /**
     * 获取文件夹下的所有配置文件
     * @return
     * @throws IOException
     */
    public List<ConfigFileInfo> getAllConfigFiles() throws IOException {
        File file = ResourceUtils.getFile(FILE_DIR);
        File[] files = file.listFiles();
        List<ConfigFileInfo> infos = new LinkedList<>();
        for(File f : files){
            String fileName = f.getName();
            if(fileName.startsWith(FILE_PRE) && fileName.endsWith(FILE_SUF)){
                fileName = fileName.replace(FILE_PRE,"").replace(FILE_SUF,"");
                DefaultConfiguration config = getConfig(fileName);
                if(config!=null && config.getConfig().isShowInFront() ){
                    infos.add(new ConfigFileInfo(fileName,config.gainConfigName(),config.gainConfigDesc()));
                }
            }
        }
        return infos;
    }

    /**
     * 获取xml文件的内容
     * @param fileName 文件名称
     * @return
     * @throws IOException
     */
    private String getFileContent(String fileName) throws IOException {
        String fileFullName = FILE_PRE + fileName + FILE_SUF;
        File file = ResourceUtils.getFile(FILE_DIR+ fileFullName);
        InputStream inputStream = new FileInputStream(file);
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        while ((line = br.readLine()) != null) {
            buffer.append(line);
        }
        br.close();
        return buffer.toString();
    }

    private String getRedisContent(String fileName){
        return this.readFromRedis(fileName);
    }


    /**
     * 将xml文件转换成默认的配置JavaBean
     * @param fileName
     * @return
     * @throws IOException
     */
    public DefaultConfiguration getConfig(String fileName) throws IOException {
        String text = getFileContent(fileName);
        JSONObject xmlJSONObj = XML.toJSONObject(text);
        DefaultConfiguration config = JSON.parseObject(xmlJSONObj.toString(),DefaultConfiguration.class);

        String text_redis = getRedisContent(fileName);
        if(StringUtils.hasLength(text_redis)){
            JSONObject xmlJSONObj_redis = XML.toJSONObject(text_redis);
            DefaultConfiguration config_redis = JSON.parseObject(xmlJSONObj_redis.toString(),DefaultConfiguration.class);

            Map<String,String> map = new HashMap<>();
            for(Attribute attr : config_redis.getConfig().getAttr()){
                map.put(attr.getName(),attr.getValue());
            }
            for(Attribute attr : config.getConfig().getAttr()){
                if(map.containsKey(attr.getName())){
                    attr.setValue(map.get(attr.getName()));
                }
            }
        }

        return config;
    }

    public <T> T getConfig(String fileName,Class<T> cls ) throws IOException {
        DefaultConfiguration config = getConfig(fileName);
        JSONObject jsonObject = new JSONObject();
        List<Attribute> attributes = config.listAttribute();
        for(Attribute attr : attributes ){
            jsonObject.putOpt(attr.getName(),attr.getValue());
        }
        return  JSON.parseObject(jsonObject.toString(),cls);
    }


    private static String json2xml(String json)  {
        JSONObject jsonObject = new JSONObject(json);
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + org.json.XML.toString(jsonObject) ;
    }

    public void save(ConfigSaveParam param) throws IOException {
        // 获取文件配置
        DefaultConfiguration config = getConfig(param.getFileName());
        // 获取配置选项
        List<Attribute> attrs = config.getConfig().getAttr();

        // 获取参数
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(param.getParam());
        // 修改参数
        for(Attribute attr : attrs){
            if(jsonObject.containsKey(attr.getName())){
                attr.setValue(jsonObject.getString(attr.getName()));
            }
        }

        String xml = IntegrationService.json2xml( JSON.toJSONString(config));

        log.info(xml);
        String key = CONFIG_PRE + param.getFileName();
        this.save2Redis(key,xml);
    }

    private void save2Redis(String key ,String xml){
        RBucket<String> bucket = client.getBucket(key);
        xml = xml.replace("&quot;" , "\"");
        bucket.set(xml);
    }

    private String readFromRedis(String fileName){
        String key = CONFIG_PRE + fileName;
        RBucket<String> bucket = client.getBucket(key);
        if (bucket.isExists()){
            String result = bucket.get();
            return result;
        }
        return null;
    }



}
